From 928609f0362884d327b8ff445c83f1f4e48ee846 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Mon, 4 Jun 2007 14:03:42 -0600 Subject: [PATCH] [IA64] Prevent rfi emulation with double un-cover Recently (CS 13436) rfi hyperprivop was simplified. But as a consequence rfi emulation with double un-cover is not possible anymore. Comment priv_rfi and forbid rfi emulation with double un-cover. Signed-off-by: Tristan Gingold --- xen/arch/ia64/xen/hyperprivop.S | 18 ++++++++++++++++-- xen/arch/ia64/xen/privop.c | 9 +++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/xen/arch/ia64/xen/hyperprivop.S b/xen/arch/ia64/xen/hyperprivop.S index 2fe754cb86..58269fc110 100644 --- a/xen/arch/ia64/xen/hyperprivop.S +++ b/xen/arch/ia64/xen/hyperprivop.S @@ -1029,8 +1029,22 @@ ENTRY(slow_vcpu_rfi) ld8 r22=[r22];; tbit.z p6,p0=r22,63 (p6) br.spnt.few dispatch_break_fault ;; - // if vips is valid, discard current register frame - // don't need dorfirfi any more + // If vifs.v is set, we have two IFS to consider: + // * the guest IFS + // * the hypervisor IFS (validated by cover) + // Because IFS is copied to CFM and is used to adjust AR.BSP, + // virtualization of rfi is not easy. + // Previously there was a two steps method (a first rfi jumped to + // a stub which performed a new rfi). + // This new method discards the RS before executing the hypervisor + // cover. After cover, IFS.IFM will be zero. This IFS would simply + // clear CFM but not modifying AR.BSP. Therefore the guest IFS can + // be used instead and there is no need of a second rfi. + // Discarding the RS with the following alloc instruction just clears + // CFM, which is safe because rfi will overwrite it. + // There is a drawback: because the RS must be discarded before + // executing C code, emulation of rfi must go through an hyperprivop + // and not through normal instruction decoding. alloc r22=ar.pfs,0,0,0,0 br.spnt.few dispatch_break_fault ;; diff --git a/xen/arch/ia64/xen/privop.c b/xen/arch/ia64/xen/privop.c index 559c3e44ea..8ca6e49b8b 100644 --- a/xen/arch/ia64/xen/privop.c +++ b/xen/arch/ia64/xen/privop.c @@ -31,6 +31,15 @@ Privileged operation emulation routines static IA64FAULT priv_rfi(VCPU * vcpu, INST64 inst) { + REGS *regs = vcpu_regs(vcpu); + if (PSCB(vcpu, ifs) > 0x8000000000000000UL + && regs->cr_ifs > 0x8000000000000000UL) { + panic_domain(regs, + "rfi emulation with double uncover is " + "impossible - use hyperprivop\n" + " ip=0x%lx vifs=0x%lx ifs=0x%lx\n", + regs->cr_iip, PSCB(vcpu, ifs), regs->cr_ifs); + } return vcpu_rfi(vcpu); } -- 2.30.2